
\section{Goal}
Since our language is aimed at designing multiple kinds of board games
rather than limit to only one kind of games, testing is essential
and must cover every possible cases, otherwise the results we get
would be dramatically different.

Testing is evolved throughout the compiler development, not only at
the final stage, but also from the very beginning when the grammar
was implemented. Our approach, probably like many others, is to test
each piece of our compiler and sew them together to conduct the final
test.
\section{Unit testing}

To make the process of designing and implementing games fun and convenient,
our language is quite flexible, which leads to a more complex grammar.
Since the grammar laid the base for the whole interpreter, any tiny
errors in the grammar may result in a huge waste of time in the implementing
period. So we designed the grammar and built the AST parallelly. Since
we designed the grammar bottom up, every time we designed a part of
the grammar , we built the according brunches of the AST, so that
we can test if the tokens could be parsed and concluded to the root
of that brunch. With the progress of the project, the grammar became
more and more complete, and the different parts of the tree has been
combined together, we wrote tree traversal utilities for members to
test their own part of the AST is right.


\section{Regression testing}

Since many things can go wrong, and bugs could be hidden anywhere,
regression test is important in the project. What we want to guarantee
is what changes we make right now do not break the code we have had
before. Thus, only testing the changes we made currently is not enough.
Every time a team member makes any modification to the system, he
has to run through all the previous tests again to make sure that
the system still works well, which is quite cubersome and time consuming.
As a result, we decide to build a script to automate this procedure.
The script, written in shell, used makefile to compiles the source
files of the interpreter, and then test the newly generaetd interpreter
on all the test cases we have. When we add new features to the system,
we create new test files for it and update the test script.

This script greatly simplified our regression test job. At any time
after the code modification, the batched test will immediately tell
us whether we have broken some previously good code. Also, hundreds
of small testing files are avoided. This approach eventually makes
our testing systematic and assorted.


\section{System testing}

When every member has finished his part, we integrate them together.
Since we first set the data structure and then develop the front end
and back end parallelly, when we do system testing, errors might not
be easily found by those small code segments, larger testing programs
with all the language features of Tactics are extremely necessary.
All programs in the chapter of tutorial, especially those complete
examples, were acting as testing codes. These examples not only helped
us find some bugs, but also deepened of our understanding of the whole
language. Please refer to the chapter of tutorial for these testing
examples.
